package com.fingard.dsp.bank.directbank.gxnx01;

import java.util.Calendar;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2018/10/10.
 */
public class GXNX01SinglePay extends GXNX01Base implements ISinglePay {

    /**
     * 单笔支付
     * @param p_req1908
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        return d_1908_SglPayA(p_req1908);
    }

    /**
     * 公网-单笔支付
     * @param p_req1908
     * @return
     * @throws Exception
     */
    public RetAtsSingle d_1908_SglPayA(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        try {
            //签名原文
            String signDataStr="";
            if(p_req1908.singleDetail.sameBnk.equals("0")){
                signDataStr=p_req1908.singleDetail.payAct+"|"+p_req1908.singleDetail.payName+"|"
                        +p_req1908.singleDetail.recAct+"|"+p_req1908.singleDetail.recName+"|"
                        +p_req1908.singleDetail.cnapsCode+"|"+p_req1908.singleDetail.payAmount;
            }else {
                signDataStr=p_req1908.singleDetail.payAct+"|"+p_req1908.singleDetail.payName+"|"
                        +p_req1908.singleDetail.recAct+"|"+p_req1908.singleDetail.recName+"|"
                        +p_req1908.singleDetail.payAmount;
            }
            //获取签名后的数据
            String signData=sendBankBySigned(signDataStr);
            if("".equals(signData)){
                detail.respCode = "-1";
                detail.respInfo = "获取签名后的数据失败，请求报文发送失败";
            }else {
                XmlTextWriter xmlTextWriter = new XmlTextWriter();
                GXNX01Header header = new GXNX01Header();
                if(p_req1908.singleDetail.sameBnk.equals("0")){
                    header.tranCode ="CBE004";//跨行
                }else {
                    header.tranCode ="CBE003";//同行
                }
                writeCommonHeader(xmlTextWriter,header);
                //拼接请求报文体
                XElement body = new XElement("ReqParam","");
                body.addChild(new XElement("serialNo",p_req1908.singleDetail.askNumber));//流水号
                body.addChild(new XElement("payAccount",p_req1908.singleDetail.payAct));//转出账号
                body.addChild(new XElement("currencyType",convertCurToBank(p_req1908.singleDetail.payCur)));//币种
                body.addChild(new XElement("payAccountName",p_req1908.singleDetail.payName));//转出户名
                if (p_req1908.singleDetail.sameBnk.equals("0")){
                    body.addChild(new XElement("fastFlg",p_req1908.singleDetail.paySpd));//加急标志 0不加 1加
                }
                body.addChild(new XElement("recAccount",p_req1908.singleDetail.recAct));//转入账号
                body.addChild(new XElement("recAccountName",p_req1908.singleDetail.recName));//转入户名
                if (p_req1908.singleDetail.sameBnk.equals("0")){
                    body.addChild(new XElement("recBankName",p_req1908.singleDetail.cnapsName));//转入行名
                    body.addChild(new XElement("recBankCode",p_req1908.singleDetail.cnapsCode));//转入行号
                }
                body.addChild(new XElement("tranAmt",p_req1908.singleDetail.payAmount));//转出金额
                body.addChild(new XElement("payUse",p_req1908.singleDetail.purpose));//用途
                body.addChild(new XElement("remark",p_req1908.singleDetail.memo));//备注
                body.addChild(new XElement("branchId",bankFront.org));//机构号
                body.addChild(new XElement("signDataStr",signDataStr.trim()));//签名原文
                body.addChild(new XElement("signData",signData.trim()));//签名后数据
                nodeAnalysis(p_req1908.singleDetail.srcXElement,body,getCharset());
                xmlTextWriter.writeXElement(body);
                xmlTextWriter.writeEndDocument();
                String[] bankResult = sendToBank(xmlTextWriter.toXmlString());

                //测试
                //bankResult[0]="";
                //bankResult[1]="0000||#<?xml version=\"1.0\" encoding=\"utf-8\"?><QLBankData>  <opRep>    <opResult>      <payBal>100.00</payBal>      <payBalAvl>100.00</payBalAvl>      <totalAmt>0</totalAmt>      <errorCode></errorCode>      <errorMessage></errorMessage>    </opResult>  </opRep></QLBankData>\n";
                //WriteBankLogStep2(bankResult[1]);

                if(bankResult[0].length()==0){
                    String[] result=bankResult[1].split("\\|");
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader xmlSbReader = loadBankRespXmlReader(result[2].substring(1),tmpSbMsg);
                    if(xmlSbReader!=null){
                        String rspCode = result[0];
                        String rspMsg = result[1];
                        if(isActiveRetCode(rspCode)){
                            String errorCode=xmlSbReader.getFirstText("/QLBankData/opRep/opResult/errorCode");//错误码
                            if(!"000000".equals(errorCode)){//请求发生异常
                                detail.respCode ="0";
                                detail.respInfo = xmlSbReader.getFirstText("/QLBankData/opRep/opResult/errorMessage");//错误信息
                                //detail.transState = xmlSbReader.getFirstText("/QLBankData/opRep/opResult/errorCode");//错误码
                                detail.transState = "1111";//银行不提供错误码标准，暂时全部用1111代替
                                detail.payInfoCode = detail.transState;
                                detail.reqSeqID = p_req1908.singleDetail.askNumber;
                            }else {
                                detail.respCode ="0";
                                detail.respInfo = rspMsg;
                                detail.transState = rspCode;
                                detail.payInfoCode = detail.transState;
                                detail.reqSeqID = p_req1908.singleDetail.askNumber;
                            }
                        }else {
                            detail.respCode ="0";
                            detail.respInfo = xmlSbReader.getFirstText("/QLBankData/opRep/opResult/errorMessage");//错误信息
                            //detail.transState = xmlSbReader.getFirstText("/QLBankData/opRep/opResult/errorCode");//错误码
                            detail.transState = "1111";//银行不提供错误码标准，暂时全部用1111代替
                            detail.payInfoCode = detail.transState;
                            detail.reqSeqID = p_req1908.singleDetail.askNumber;
                        }
                    }else {
                        detail.respCode ="-1";
                        detail.respInfo = tmpSbMsg.toString();
                    }
                }else if (bankResult[0].equals(ConnState.FAIL)) {
                    detail.respCode = "0";
                    detail.respInfo = bankResult[1];
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
                    detail.transState = PaymentState.FAIL_Payment;
                    detail.payInfoCode = bankResult[0];
                } else{
                    detail.respCode ="-1";
                    detail.respInfo = bankResult[1];
                }
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
            WriteBankLogLn("同行或者跨行转账出现异常:"+e);
        }
        retAts.writeRetDetail(detail);
        return retAts;
    }

    /**
     * 支付状态查询
     * @param p_req1944
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        return d_1944_QrySglPayA(p_req1944);
    }

    /**
     * 公网 付款状态查询
     * @param p_req1944
     * @return
     * @throws Exception
     */
    public RetAtsSingle d_1944_QrySglPayA(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        try{
            String startDate=p_req1944.bgnDate.substring(0,10).replaceAll("-","");
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(Format.Date8Format.parse(startDate));
            tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);//起始时间+1
            String endDate=Format.Date8Format.format(tmpCalendarFrom.getTime());
            //签名原文
            String signDataStr=p_req1944.payAct + "|" + convertCurToBank(p_req1944.payCur) + "|"
                    +startDate+"|"+endDate;
            //获取签名后的数据
            String signData=sendBankBySigned(signDataStr);
            if("".equals(signData)){
                detail.respCode = "-1";
                detail.respInfo = "获取签名后的数据失败，请求报文发送失败";
            }else {
                XmlTextWriter xmlTextWriter = new XmlTextWriter();
                GXNX01Header header = new GXNX01Header();
                header.tranCode ="CBE005";
                writeCommonHeader(xmlTextWriter,header);
                if(p_req1944.askNumber.isEmpty()){
                    detail.respCode ="-1";
                    detail.respInfo = "财务系统交易流水号不能为空";
                }else {
                    xmlTextWriter.writeStartElement("ReqParam");
                    xmlTextWriter.writeElementString("accountNo", p_req1944.payAct);
                    xmlTextWriter.writeElementString("serialNo", p_req1944.askNumber);
                    xmlTextWriter.writeElementString("currencyType", convertCurToBank(p_req1944.payCur));
                    xmlTextWriter.writeElementString("beginDate", startDate);
                    xmlTextWriter.writeElementString("endDate", endDate);
                    xmlTextWriter.writeElementString("branchId", bankFront.org);//机构号
                    xmlTextWriter.writeElementString("signDataStr", signDataStr.trim());//签名原文
                    xmlTextWriter.writeElementString("signData", signData.trim());//签名后数据
                    xmlTextWriter.writeEndElement();
                    xmlTextWriter.writeEndDocument();
                    String[] bankResult = sendToBank(xmlTextWriter.toXmlString());

                    //测试
                    //bankResult[0]="";
                    //bankResult[1]="0000||#<?xml version=\"1.0\" encoding=\"utf-8\"?><QLBankData>    <opRep>        <opResult>            <customerHostNo>1114114011</customerHostNo>            <customerId>111111111</customerId>            <customerNameCN>哈哈</customerNameCN>            <turnPageTotalQnt>1</turnPageTotalQnt>            <list>                <row>                    <orderFlowNo>1114114011</orderFlowNo>                    <transferDate>20181026112451</transferDate>                    <payAccount>1114114011</payAccount>                    <payAccountName>哈哈</payAccountName>                    <recAccount>1114114011</recAccount>                    <recAccountName>哈哈</recAccountName>                    <tranAmt>100.00</tranAmt>                    <currencyType>CNY</currencyType>                    <orderState>90</orderState>                    <remark></remark>                    <hostSeqNb>1114114011</hostSeqNb>                </row>            </list>        </opResult>    </opRep></QLBankData>\n";
                    //WriteBankLogStep2(bankResult[1]);

                    if (bankResult[0].length() == 0) {
                        String[] result=bankResult[1].split("\\|");
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader xmlSbReader = loadBankRespXmlReader(result[2].substring(1), tmpSbMsg);
                        if (xmlSbReader != null) {
                            String rspCode = result[0];//响应码
                            String rspMsg = result[1];//响应结果
                            if (isActiveRetCode(rspCode)) {
                                //符合条件的数为0，说明交易未生成
                                if("0".equals(xmlSbReader.getFirstText("/QLBankData/opRep/turnPageTotalQnt"))){
                                    detail.respCode = "0";
                                    detail.respInfo = "没有符合条件的流水";
                                    detail.reqSeqID = p_req1944.askNumber;//流水
                                    detail.transState = "91";//状态: 91失败
                                    detail.payInfoCode = detail.transState;
                                }else {
                                    while (xmlSbReader.read("/QLBankData/opRep/opResult/list/row")){
                                        XElement readXElement = xmlSbReader.readedXElement;
                                        detail.respCode = "0";
                                        detail.respInfo = "";
                                        detail.reqSeqID = readXElement.getSingleTextNotNull("orderFlowNo");//流水
                                        detail.transState = readXElement.getSingleTextNotNull("orderState");//状态
                                        detail.payInfoCode = detail.transState;
                                    }
                                }
                            } else {
                                detail.respCode = "-1";
                                detail.respInfo = rspMsg.toString();
                            }
                        } else {
                            detail.respCode = "-1";
                            detail.respInfo = tmpSbMsg.toString();
                        }
                    } else {
                        detail.respCode = "-1";
                        detail.respInfo = bankResult[1];
                    }
                }
            }
        }catch (Exception e){
            detail.respCode = "-1";
            detail.respInfo = e.getMessage();
            e.printStackTrace();
        }
        retAts.writeRetDetail(detail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
